package vip.liux.backend.application.service.product;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.factory.Mappers;
import vip.liux.contracts.infrastructure.automap.IgnoreAudited;
import vip.liux.contracts.infrastructure.automap.MapMapper;
import vip.liux.contracts.infrastructure.automap.MapStructConfig;
import vip.liux.contracts.models.product.Brand;
import vip.liux.contracts.models.product.Category;
import vip.liux.contracts.models.product.Product;
import vip.liux.contracts.models.product.ProductDetail;
import vip.liux.contracts.shared.value.Select;

import java.util.List;

@Mapper(config = MapStructConfig.class, uses = {MapMapper.class})
public interface AutoMapperProfile {

    AutoMapperProfile INSTANCE = Mappers.getMapper(AutoMapperProfile.class);

    @IgnoreAudited
    @Mapping(target = "brandNo", ignore = true)
    Brand toEntity(CreateBrandDto brandDto);

    BrandDto toDto(Brand brand);

    @IgnoreAudited
    @Mapping(target = "brandNo", ignore = true)
    void partialUpdate(CreateBrandDto brandDto, @MappingTarget Brand brand);

    @Mapping(target = "type", ignore = true)
    @Mapping(target = "level", ignore = true)
    @Mapping(target = "catNo", ignore = true)
    @IgnoreAudited
    Category toEntity(CreateCategoryDto categoryDto);

    @Mapping(target = "parent", ignore = true)
    @Mapping(target = "children", ignore = true)
    CategoryDto toDto(Category category);

    @Mapping(target = "value", source = "brandNo")
    @Mapping(target = "label", source = "brandName")
    Select toSelectOption(Brand brand);

    @IgnoreAudited
    @Mapping(target = "spu", ignore = true)
    @Mapping(target = "sku", ignore = true)
    ProductDetail toEntity(CreateProductDto.CreateProductDetailDto d);

    @Mapping(target = "catRootName", ignore = true)
    @Mapping(target = "catParentName", ignore = true)
    @Mapping(target = "catName", ignore = true)
    @Mapping(target = "brandName", ignore = true)
    ProductSpuDto toSpuDto(Product product, List<ProductDetail> details);

    ProductSpuDto.ProductSpuDetailDto toSpuDetailDto(ProductDetail productDetail);

    @Mapping(target = "catRootName", ignore = true)
    @Mapping(target = "catParentName", ignore = true)
    @Mapping(target = "catName", ignore = true)
    @Mapping(target = "brandName", ignore = true)
    @Mapping(source = "product.spu", target = "spu")
    @Mapping(source = "product.stockTotal", target = "stockTotal")
    ProductSkuDto toSkuDto(Product product, ProductDetail productDetail);
}
